﻿using NetworkLib.Utilities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PBO.Network
{
    public abstract class DataByteArray : TopObject
    {
        /// <summary>
        /// 支持无参构造函数
        /// </summary>
        public DataByteArray() { }

        public abstract void Read(ByteArray byteArray);

        public abstract void Write(ByteArray byteArray);

        #region internal

        public static T FromByteArray<T>(ByteArray byteArray) where T : DataByteArray
        {
            var item = Activator.CreateInstance<T>();
            item.Read(byteArray);
            return item;
        }

        #region array

        public static T[] ReadArray<T>(ByteArray byteArray) where T : DataByteArray
        {
            int count = byteArray.ReadInt();
            var array = new T[count];
            for (int i = 0; i < count; i++)
            {
                array[i] = FromByteArray<T>(byteArray);
            }
            return array;
        }

        public static void WriteArray<T>(T[] list, ByteArray byteArray) where T : DataByteArray
        {
            byteArray.WriteInt(list.Length);
            foreach (T item in list)
            {
                item.Write(byteArray);
            }
        }

        public static T[] ReadArray<T>(ByteArray byteArray, Func<ByteArray, T> fun)
        {
            int count = byteArray.ReadInt();
            var array = new T[count];
            for (int i = 0; i < count; i++)
            {
                array[i] = fun(byteArray);
            }
            return array;
        }

        public static void WriteArray<T>(T[] list, ByteArray byteArray, Action<ByteArray, T> sub)
        {
            byteArray.WriteInt(list.Length);
            foreach (T item in list)
            {
                sub(byteArray, item);
            }
        }

        #endregion

        #region list

        public static List<T> ReadList<T>(ByteArray byteArray) where T : DataByteArray
        {
            int count = byteArray.ReadInt();
            var list = new List<T>(count);
            for (int i = 0; i < count; i++)
            {
                var item = FromByteArray<T>(byteArray);
                list.Add(item);
            }
            return list;
        }

        public static void WriteList<T>(List<T> list, ByteArray byteArray) where T : DataByteArray
        {
            byteArray.WriteInt(list.Count);
            foreach (T item in list)
            {
                item.Write(byteArray);
            }
        }

        public static List<T> ReadList<T>(ByteArray byteArray, Func<ByteArray, T> fun)
        {
            int count = byteArray.ReadInt();
            var list = new List<T>(count);
            for (int i = 0; i < count; i++)
            {
                var item = fun(byteArray);
                list.Add(item);
            }
            return list;
        }

        public static void WriteList<T>(List<T> list, ByteArray byteArray, Action<ByteArray, T> sub)
        {
            byteArray.WriteInt(list.Count);
            foreach (T item in list)
            {
                sub(byteArray, item);
            }
        }

        #endregion

        #endregion
    }
}
